package it.poste.il.compensatore.aop;

import it.poste.il.compensatore.utilities.LoggerCompensatore;

import java.util.Arrays;
import java.util.Date;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;

/**
 * Class that is responsible for logging the start and return of the method execution.
 */
@Aspect
public class LogAspect {

	/**
	 * The Log Factory.
	 */
	private static LoggerCompensatore loggerF;

	/**
	 * Method that returns the Log Factory.
	 * @return LogFactory The Log Factory.
	 */
	public LoggerCompensatore getLoggerF() {
		return loggerF;
	}

	/**
	 * Method that sets the Log Factory.
	 * @param LogFactory Log Factory to set.
	 * @return void
	 */
	public void setLoggerF(LoggerCompensatore loggerF) {
		this.loggerF = loggerF;
	}
	
	/**
	 * Applied to each method following to relaunch of an exception.
	 * @param JoinPoint Join-Point for the aspect.
	 * @return void
	 */
	//@AfterThrowing("execution(* *.*(..))")
	public void afterThrowing(JoinPoint jp) throws Throwable {
		LoggerCompensatore logger = (LoggerCompensatore) loggerF.getLogger(this);
		logger.error("\tError: " + jp.getSignature().getName());
	}
	
	/**
	 * Applied before of execution public's methods of classes having the word DAO in the name
	 * @param JoinPoint Join-Point for the aspect.
	 * @return void
	 */
	//@Before("execution(public * it.poste.il.compensatore.dao.*Dao.*(..))")
	public void beforeAdvice(JoinPoint jp) {
		// Log prima dell'invocazione del metodo
		LoggerCompensatore logger = (LoggerCompensatore) loggerF.getLogger(this);
		logger.info("[" + new Date() + "]\n\t" 
				+  jp.getTarget().getClass() + "."  +  jp.getSignature().getName()
				+  "\n\tArguments: "+ Arrays.toString(jp.getArgs()));	
	}
	
	/**
	 * Applied after of execution public's methods of classes having the word DAO in the name
	 * @param JoinPoint Join-Point for the aspect.
	 * @return void
	 */
	//@AfterReturning(pointcut = "execution(public * it..*Dao.*(..))", returning = "returnValue")
	public void afterReturning(JoinPoint jp, Object returnValue) throws Throwable {
		// Log del risultato dell'invocazione del metodo
		LoggerCompensatore logger = (LoggerCompensatore) loggerF.getLogger(this);
		logger.info("\tResult: "+ returnValue);	
	}	
	
}
